/**
  ******************************************************************************
  * File Name          : e_flash.c
  * Description        : flash相关的用户操作
  *
  ******************************************************************************
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "Sysflash.h"
#include "string.h"

/* define ------------------------------------------------------------------*/

/* Exported typedef ------------------------------------------------------------------*/



/* struct data ------------------------------------------------------------------*/



/* Function ------------------------------------------------------------------*/
/**
  * 函数功能: 从指定地址开始写入指定长度的数据
  * 输入参数: WriteAddr:起始地址(此地址必须为2的倍数!!)
  *           pBuffer:数据指针
  *           NumToWrite:半字(16位)数(就是要写入的16位数据的个数.)
  * 返 回 值: 无
  * 说    明：无
  */
/* define ------------------------------------------------------------------*/

#define STM_SECTOR_SIZE		2048
#define STM32_FLASH_BASE 	0x08000000 	//FLASH 起始地址
#define STM32_FLASH_SIZE 	128 	 		//闪存容量

#define u16 uint16_t
#define u32 uint32_t

/* Exported typedef ------------------------------------------------------------------*/

/**
  * @brief  Gets the page of a given address
  * @param  Addr: Address of the FLASH Memory
  * @retval The page of a given address
  */
uint32_t GetPage(uint32_t Addr)
{
  return (Addr - FLASH_BASE) / FLASH_PAGE_SIZE;;
}

/* struct data ------------------------------------------------------------------*/

static uint8_t STMFLASH_BUF[STM_SECTOR_SIZE];//



/* Function ------------------------------------------------------------------*/

void E_CFG_EraseFlash(uint32_t Addr)
{
	u32 secpos;	   			//页地址
	u16 offset;	   			//偏移量
//	u16 odd; 					//剩余量
	u32 offaddr;  		 	//去掉0x8000000后的地址
	
	offaddr=Addr-STM32_FLASH_BASE;			//实际偏移地址
	secpos=offaddr/STM_SECTOR_SIZE;			//页地址
	offset=(offaddr%STM_SECTOR_SIZE);		//扇区内偏移地址
//	odd=STM_SECTOR_SIZE/2-offset;			//扇区内剩余空间
	
	//1、解锁FLASH
	HAL_FLASH_Unlock();

    //2擦除FLASH
    //初始化FLASH_EraseInitTypeDef
    FLASH_EraseInitTypeDef f;
    f.TypeErase = FLASH_TYPEERASE_PAGES;
    f.Page = secpos - 1;
    f.NbPages = 1;
    //设置PageError
    uint32_t PageError = 0; 
    //调用擦除函数
    HAL_FLASHEx_Erase(&f, &PageError);
		//锁定FLASH
		HAL_FLASH_Lock();
}


uint64_t write_data;

FLASH_EraseInitTypeDef EraseInitStruct = {0};

void E_CFG_WriteFlash(uint8_t *Dat,uint32_t Addr,uint16_t DatLen)
{
  uint16_t i;
  
	
	
	uint32_t FirstPage = 0, NbOfPages = 0;
	uint32_t Address = 0, PageError = 0;
	
  /* Get the 1st page to erase */
  FirstPage = GetPage(Addr);

  /* Get the number of pages to erase from 1st page */
  NbOfPages = GetPage(Addr+DatLen) - FirstPage + 1;

  /* Fill EraseInit structure*/
  EraseInitStruct.TypeErase   = FLASH_TYPEERASE_PAGES;
  EraseInitStruct.Page        = FirstPage;
  EraseInitStruct.NbPages     = NbOfPages;

    //1、解锁FLASH
	if(HAL_OK != HAL_FLASH_Unlock())
	{
		return;
	}

  if (HAL_FLASHEx_Erase(&EraseInitStruct, &PageError) != HAL_OK)
	{
		return;
	}
  

	memcpy(STMFLASH_BUF,Dat,DatLen);
	
  //写入数据
  for(i=0;i<STM_SECTOR_SIZE/8;){
    write_data=((STMFLASH_BUF[i*8+7]));
		write_data=(write_data<<8)|(STMFLASH_BUF[i*8+6]);
    write_data=(write_data<<8)|(STMFLASH_BUF[i*8+5]);
		write_data=(write_data<<8)|(STMFLASH_BUF[i*8+4]);
    write_data=(write_data<<8)|(STMFLASH_BUF[i*8+3]);
    write_data=(write_data<<8)|(STMFLASH_BUF[i*8+2]);
    write_data=(write_data<<8)|(STMFLASH_BUF[i*8+1]);
    write_data=(write_data<<8)|(STMFLASH_BUF[i*8]);
    if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Addr+i*8, write_data) == HAL_OK)
    {
      i++;
    }
		else
		{
			while(1);
		}
//    HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, addr+i*8,write_data);i++;
  }
  //锁定FLASH
  HAL_FLASH_Lock();
}






/************************ (C) COPYRIGHT INLEEQ *****END OF FILE****/
